<!--
 * @Author: liyin 2179253556@qq.com
 * @Date: 2023-03-20 13:51:35
 * @LastEditors: liyin 2179253556@qq.com
 * @LastEditTime: 2025-10-23 09:51:37
 * @FilePath: Managers.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
    <div class="user-info-box">
        <SearchComp @clear="clearHandle">
            <RowItem label="关键字" :count="1">
                <el-input clearable placeholder="请输入用户名称/昵称关键字搜索" v-model="personQuery.key_word" prefix-icon="Search"
                    @input="search" style="width: 100%">
                </el-input>
            </RowItem>
            <RowItem label="选择状态" :count="2">
                <el-select :teleported="false" v-model="personQuery.status" style="width:100%;" clearable
                    placeholder="请选择状态" @change="search">
                    <el-option label="有效" value="1"></el-option>
                    <el-option label="无效" value="0"></el-option>
                </el-select>
            </RowItem>
            <RowItem label="选择角色" :count="3">
                <el-select :teleported="false" v-model="personQuery.role_uuid" style="width:100%;" clearable
                    placeholder="请选择角色" @change="search">
                    <el-option v-show="item.uuid != '26258978-74f0-5604-6c35-78781b5f254d'"
                        v-for="(item, index) in roleList" :key="index" :label="item.role_name"
                        :value="item.uuid"></el-option>
                </el-select>
            </RowItem>
        </SearchComp>
        <Table :data="tableData" :config="tableConfig" @handleEdit="handleEdit" :showLoading="loading" :total="total"
            @sizeChange="sizeChange" @CurrentChange="CurrentChange">
            <el-button type="primary" @click="Add">添加账号</el-button>
            <el-button type="primary" class="white-bg-btn" plain @click="Download">下载模板</el-button>
            <el-upload style="display: inline-block; vertical-align: middle;margin-left: 12px;" :http-request="toSheet">
                <el-button type="primary" class="white-bg-btn" plain>批量导入</el-button>
            </el-upload>
        </Table>
        <!-- 添加权限弹窗 -->
        <Model :title="addForm.uuid ? '编辑账号' : '添加账号'" :modelShow="dialogVisible" width="40"
            @cancel="resetForm(addFormRef)" @confirm="submitForm(addFormRef)">
            <el-form label-width="80px" size="default" :rules="rules" :model="addForm" ref="addFormRef">
                <el-row :gutter="20">
                    <el-col :span="12">
                        <el-form-item label="账号名称" prop="account">
                            <el-input type="text" v-model="addForm.account" minlength="5" maxlength="20"  show-word-limit placeholder="请输入账号名称" clearable></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="账号昵称" prop="name">
                            <el-input v-model="addForm.name" placeholder="请输入账号昵称" clearable></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="12">
                        <el-form-item label="手机号码" prop="mobile">
                            <el-input v-model="addForm.mobile" @change="changeInput" clearable
                                placeholder="请输入手机号码"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="角色权限" prop="role_uuid">
                            <el-select :teleported="false" v-model="addForm.role_uuid" style="width:100%;" clearable
                                placeholder="请选择角色权限">
                                <el-option v-show="item.uuid != '26258978-74f0-5604-6c35-78781b5f254d'"
                                    v-for="(item, index) in roleList" :key="index" :label="item.role_name"
                                    :value="item.uuid"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="24">
                        <el-form-item label="登录密码" prop="passwd" :required="!addForm.uuid">
                            <el-input type="password" v-model="addForm.passwd" :readonly="readonlyFlag"
                                autocomplete='off' @focus="handlerIpClick" show-password
                                placeholder="8-20位数字,大小写字母特殊符号组合密码">
                            </el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="确认密码" prop="passwd2" :required="!addForm.uuid">
                            <el-input type="password" v-model="addForm.passwd2" :readonly="readonlyFlag"
                                autocomplete='off' @focus="handlerIpClick" show-password placeholder="请再次输入密码">
                            </el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="8">
                        <el-form-item label="上传头像" prop="inch">
                            <CropperImage :avatar="addForm.inch" @changeImage="changeImage" @clearImage="clearImage"
                                :width="66" :height="66" :radius="33" :autoCropWidth="200" :autoCropHeight="200"
                                :showCloceIcon="false" dir="inch" :fixedRate="[1,1]">
                            </CropperImage>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="性别" prop="sex">
                            <el-radio-group v-model="addForm.sex">
                                <el-radio-button label="1">男</el-radio-button>
                                <el-radio-button label="2">女</el-radio-button>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="状态" prop="status">
                            <el-radio-group v-model="addForm.status">
                                <el-radio-button label="1">有效</el-radio-button>
                                <el-radio-button label="0">无效</el-radio-button>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="过期时间" prop="expire_time">
                            <el-date-picker v-model="addForm.expire_time" type="datetime" placeholder="请选择过期时间"
                                align="center" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" clearable
                                :teleported="false"></el-date-picker>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="备注" prop="intro">
                            <el-input type="textarea" v-model="addForm.intro" placeholder="请输入备注"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
        </Model>
        <!-- 导入预览 -->
        <ExportModify :showdialogVisible="showdialogVisible" @modelCancel="modelCancel2" @getList="getList"
            :ImportDate="ImportDate" :errorNum="errorNum">
        </ExportModify>
        <!-- 设置文章权限 -->
        <!-- ExportCol -->
        <FilterModule :filterVisible="filterVisible" :ExportCol="ExportCol" :editUserId="editUserId" @getList="getList" @modelCancel="modelCancel3">
        </FilterModule>
    </div>
</template>
<script setup lang="ts">
import $util from '../../util/util'
import { ref, h, onMounted, reactive, nextTick, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { PiniaStore } from '../../store'
import ExportModify from './ExportModify.vue'
import FilterModule from './FilterModule.vue'
import { getManagersList, addManagers, editManagers, delManagers, RoleList, importAccountExcel,getUserModuleAuth } from '../Api/Operation'
import Md5 from 'js-md5'
const store = PiniaStore()
const validatePass = (rule: any, value: any, callback: any) => {
    if (!addForm.uuid && value === '') {
        callback(new Error('请输入密码'))
    } else if (addForm.uuid && !addForm.passwd && addForm.passwd2) {
        callback(new Error('请输入密码'))
    } else if (value !== '' && !/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[._~!@#$^&*])[A-Za-z0-9._~!@#$^&*]{8,20}$/g.test(value)) {
        callback(new Error('请输入包含英文字母大小写、数字和特殊符号的 8-20 位组合密码'))
    } else {
        callback()
    }
}
const validatePass2 = (rule: any, value: any, callback: any) => {
    if (!addForm.uuid && value === '') {
        callback(new Error('请再次输入密码'))
    } else if (value !== addForm.passwd) {
        callback(new Error('两次输入密码不一致!'))
    } else {
        callback()
    }
}
// 手机号验证
const validatePhone = (rule: any, value: any, callback: any) => {
    console.log(isChange.value || !addForm.uuid)
    if (value === "") {
        callback(new Error("请输入手机号码"));
    } else if (isChange.value || !addForm.uuid) {
        if (!/^1[3456789]\d{9}$/.test(value)) {
            callback(new Error("请输入正确的手机号码"));
        } else {
            callback();
        }
    } else {
        callback();
    }
}
const filterVisible = ref(false) // 筛选条件
const loading = ref(false)
const personQuery = reactive({
    key_word: '',
    status: '',
    role_uuid: '',
    page: 1,
    page_size: store.pageQuery.page_size,
})
const readonlyFlag = ref(true)
const handlerIpClick = () => {
    readonlyFlag.value = false
}
const dialogVisible = ref(false)
const addFormRef = ref<FormInstance>()
const addForm = reactive({
    uuid: '',
    account: '',
    passwd: '',
    passwd2: '',
    //状态 1-有效 0-无效
    status: '1',
    name: '',
    expire_time: '',
    mobile: '',
    inch: '',
    role_uuid: '',
    sex: '1',
    intro: '',
})
const rules = reactive<FormRules>({
    account: [
        { required: true, message: '请输入账号名称', trigger: 'blur' },
        // 新增长度校验规则
        { min: 5, max: 20, message: '账号名称长度需在5到20个字符之间', trigger: 'blur' }
    ],
    name: [{ required: true, message: '请输入账号昵称', trigger: 'blur' }],
    // mobile: [{ required: true, validator: validatePhone, trigger: 'blur' }],
    passwd: [{ required: true, validator: validatePass, trigger: 'blur' }],
    passwd2: [{ required: true, validator: validatePass2, trigger: 'blur' }],
    role_uuid: [{ required: true, message: '请选择角色权限', trigger: 'blur' }],
    expire_time: [{ required: true, message: '请选择过期时间', trigger: 'blur' }],
})
// 点击清空条件触发
const clearHandle = () => {
    personQuery.key_word = ''
    personQuery.status = ''
    personQuery.role_uuid = ''
    personQuery.page = 1
    getList()
}
// 表格数据
const total = ref(0)
const tableData = ref([])
const tableConfig = ref([
    { name: 'index', label: '序号', width: '60', type: 'index', checked: true },
    { name: 'account', label: '用户名称', type: 'change', width: '', checked: true },
    { name: 'name', label: '用户昵称', type: 'change', width: '', checked: true },
    { name: 'role_name', label: '角色权限', type: 'change', width: '', checked: true },
    { name: 'mobile', label: '手机号码', type: 'change', width: '', checked: true },
    {
        name: 'status',
        label: '账号状态',
        width: '',
        checked: true,
        type: 'status',
        formatter: [
            { name: 0, label: '无效', status: 'danger' },
            { name: 1, label: '有效', status: 'success' }
        ]
    },
    { name: 'creator_name', label: '创建人', type: 'change', width: '', checked: true },
    { name: 'create_time', label: '创建时间', type: 'change', width: '', checked: true },
    { name: 'expire_time', label: '过期时间', type: 'change', width: '', checked: true },
    { name: 'update_time', label: '更新时间', type: 'change', width: '', checked: true },
    {
        name: '',
        label: '操作',
        width: '180',
        type: 'edit',
        checked: true,
        formatter: [
            { name: 'Edit', label: '编辑', font: true, link: true },
            { name: 'Delete', label: '删除', font: true, link: true },
            { name: 'Permission', label: '文章权限', font: true, link: true },
        ]
    }
])
// 点击搜索按钮
const search = $util.debounce((val: string | number) => {
    personQuery.page = 1
    getList()
}, 500)
// 获取用户列表
const getList = async () => {
    loading.value = true
    const params = {
        ...personQuery
    }
    const res: any = await getManagersList(params)
    if (res.code !== 1) {
        loading.value = false
        return ElMessage.error(res.message)
    }
    tableData.value = res.data
    total.value = res.total
    loading.value = false
}
const isChange = ref<boolean>(false)
const changeInput = async (val: any) => {
    if (addForm.uuid) {
        isChange.value = true
    }
}
// 下载导入模板
const Download = async () => {
    window.location.href = '/ShiyizhongAdminUpload/导入账号模板.xlsx'
}
const showdialogVisible = ref<boolean>(false)
const errorNum = ref<number>(0)
const ImportDate = ref<any>([])
const toSheet = async (params: any) => {
    const formData = new FormData()
    formData.append('excel', params.file) // 要提交给后台的文件
    const res: any = await importAccountExcel(formData)
    if (res.code !== 1) return ElMessage.error(res.msg)
    ElMessage.success('导入成功!')
    ImportDate.value = res.data.list
    errorNum.value = res.data.error
    showdialogVisible.value = true
}
const modelCancel2 = (bol: boolean) => {
    showdialogVisible.value = bol
}
// 点击添加用户
const Add = async () => {
    addForm.uuid = ''
    isChange.value = false
    dialogVisible.value = true
}
const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.validate(async (valid: any) => {
        if (valid) {
            let obj: any = {
                account: addForm.account,
                passwd: addForm.passwd ? Md5(addForm.passwd) : '',
                passwd2: addForm.passwd2 ? Md5(addForm.passwd2) : '',
                status: addForm.status,
                name: addForm.name,
                expire_time: addForm.expire_time,
                mobile: !addForm.uuid ? addForm.mobile : isChange.value ? addForm.mobile : '',
                inch: addForm.inch,
                role_uuid: addForm.role_uuid,
                sex: addForm.sex,
                intro: addForm.intro
            }
            if (addForm.uuid) {
                obj.uuid = addForm.uuid
            }
            const res: any = addForm.uuid ? await editManagers(obj) : await addManagers(obj)
            if (res.code !== 1) return ElMessage.error(res.message)
            ElMessage.success(res.message)
            dialogVisible.value = false
            getList()
            formEl.resetFields()
            reset()
        } else {
            console.log('error submit!')
        }
    })
}
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    dialogVisible.value = false
    formEl.resetFields()
    reset()
}
const reset = () => {
    addForm.uuid = ''
    addForm.account = ''
    addForm.passwd = ''
    addForm.passwd2 = ''
    addForm.status = '1'
    addForm.name = ''
    addForm.expire_time = ''
    addForm.mobile = ''
    addForm.inch = ''
    addForm.role_uuid = ''
    addForm.sex = '1'
    addForm.intro = ''
}
// 点击设置菜单权限
const ExportCol = ref<any>([])
const editUserId = ref('')
const handleEdit = async (item: any, name: string) => {
    if (name === 'Edit') {
        nextTick(() => {
            addForm.uuid = item.uuid
            addForm.account = item.account
            addForm.status = item.status
            addForm.name = item.name
            addForm.expire_time = item.expire_time
            addForm.mobile = item.mobile
            addForm.inch = item.inch
            addForm.role_uuid = item.role_uuid
            addForm.sex = item.sex
            addForm.intro = item.intro
            isChange.value = false
        })
        dialogVisible.value = true
    } else if (name === 'Delete') {
        ElMessageBox({
            title: '温馨提示',
            message: h('p', { style: 'font-weight:bold;font-size: 15px;color: #333333;' }, [
                h('span', null, '您确定要删除该账号吗？'),
                h('p', { style: 'font-size: 14px;font-weight:normal;color: rgba(0,0,0,0.65);margin-top:10px;' }, '删除后将无法恢复，确定要继续吗?'),
            ]),
            showCancelButton: true,
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            beforeClose: async (action, instance, done) => {
                if (action === 'confirm') {
                    console.log(item.id)
                    const res: any = await delManagers({ uuid: item.uuid })
                    if (res.code !== 1) {
                        done()
                        return ElMessage.error(res.message)
                    }
                    ElMessage.success(res.message)
                    getList()
                    done()
                } else {
                    done()
                }
            },
        }).then((action) => {
        })
    } else if (name === 'Permission') {
        //  文章权限
        editUserId.value = item.uuid
        const res: any = await getUserModuleAuth({ user_id: item.uuid })
        if (res.code!== 1) return ElMessage.error(res.message)
        ExportCol.value = res.data[0]
        filterVisible.value = true
    }
}
const modelCancel3 = (bol: boolean) => {
    filterVisible.value = bol
}
// 点击翻页器的长度
const sizeChange = () => {
    personQuery.page_size = store.pageQuery.page_size
    getList()
}
// 点击翻页器的页码
const CurrentChange = () => {
    personQuery.page = store.pageQuery.page
    getList()
}
// 获取角色列表
const roleList = ref<any>()
const RoleListList = async () => {
    const res: any = await RoleList()
    if (res.code !== 1) return ElMessage.error(res.message)
    roleList.value = res.data
}
const changeImage = (res: any) => {
    addForm.inch = res.inch
}
const clearImage = () => {
    addForm.inch = ''
}
onMounted(() => {
    RoleListList()
    getList()
})
</script>
<style lang="scss" scoped>
.user-info-box {
    width: 100%;
}

.uploadList {
    display: flex;
    flex-flow: wrap;
    width: 100%;
}

:deep(.avatar-uploader .el-upload) {
    width: 66px;
    height: 66px;
    background: #EEEEEE;
    border-radius: 4px;
    border: 1px dashed #DCDCDC;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.4);
    box-sizing: border-box;
    // padding: 6px;
    border-radius: 50%;
}

:deep(.el-icon.avatar-uploader-icon) {
    color: #000000;
    margin-bottom: 3px;
    font-size: 14px;
    font-weight: 600;
}

:deep(.avatar-uploader) {
    margin: 0px;
    width: 66px;
}

:deep(.el-input .el-input__wrapper) {
    width: 100% !important;
    box-sizing: border-box !important;
}

:deep(.el-upload-list) {
    display: none;
}
</style>